#include "dominion.h"
#include <stdio.h>
#include "rngs.h"
#include <stdlib.h>
#include "math.h"
#include "dominion_helpers.h"
#include "testutilities.h"
#include <assert.h>

//test to see that the supply matches with k
void testK(struct gameState *g, int *k){
	int i, j;
	int inK;
	//k->length == 10
	for(i=0; i < 10; i++){
		//garden and great_hall are victory cards and should should have the same
		//8 or 12 depending on numPlayers
		if(k[i] == gardens || k[i] == great_hall){
			if(g->numPlayers == 2){
				assert(g->supplyCount[k[i]] == 8);
			}
			else{
				assert(g->supplyCount[k[i]] == 12);
			}
		}
		else{
			//all other kingdom cards should be 10 
			assert(g->supplyCount[k[i]] == 10);
		}
	}
	//see if any supply cards are present that should not be there
	for(i = adventurer; i <= treasure_map; i++){
		inK = 0;
		for(j = 0; j < 10; j++){
			if(k[j] == i){
				inK = 1;
			}
		}
		//if this supply card is not in K
		if(inK == 0){
			//printf("k[%d] = %d, supplyCount: %d\n", i, k[i], g->supplyCount[i]);
			assert(g->supplyCount[i] < 1);
		}
	}
//	printf("passed\n");
}

void testHandDeck(struct gameState *g){
	int i;
	int coppers;
	int estates;
	
	for(i=0; i < g->numPlayers; i++){
		//hand: 1, deck 2, discard 3
		/*each player should have 5 cards in both hand and deck
			7 of those cards should be coppers and 3 should be estates
		*/	
		coppers = countCardsInSet(g, i, copper, 2);
		coppers += countCardsInSet(g, i, copper, 1);

		estates = countCardsInSet(g, i, estate, 2);
		estates += countCardsInSet(g, i, estate, 1);
		assert(coppers == 7);
		assert(estates ==3);
		assert(g->deckCount[i] == 5 && "Deck is not 5 cards");
		assert(g->handCount[i] == 5 && "Count is not 5 cards");
	}
}

//returns 1 if the card is in the deck, 0 if not
int notCalledYet(int *k, int card, int top){
	int i;
	for(i=0; i < top; i++){
		if(card == k[i]){
			return 0;
		}
	}
	return 1;
}

void testVictoryCards(struct gameState *g){
	if(g->numPlayers == 2){
		assert(g->supplyCount[estate] == 8);
		assert(g->supplyCount[duchy] == 8);
		assert(g->supplyCount[province] == 8);
		assert(g->supplyCount[curse] ==10);
	}
	if(g->numPlayers == 3){
		assert(g->supplyCount[estate] == 12);
		assert(g->supplyCount[duchy] == 12);
		assert(g->supplyCount[province] == 12);
		assert(g->supplyCount[curse] == 20);
	}
	if(g->numPlayers == 4){
		assert(g->supplyCount[estate] == 12);
		assert(g->supplyCount[duchy] == 12);
		assert(g->supplyCount[province] == 12);
		assert(g->supplyCount[curse] == 30);
	}
}

void testInit(struct gameState *g){
	assert(g != NULL);
	int i;
	int kingdomCard;
	int k[10];
	getRandomNumber(0, 1); //burn the initial random number
	for(i=0; i<10; i++){
		kingdomCard = getRandomNumber(7, 26);
		while(notCalledYet(k, kingdomCard, i) == 0){
			kingdomCard = getRandomNumber(7, 26);
		}
		k[i] = kingdomCard;
	}
	
	//print kingdom cards
//	printf("Kingdom Cards:\n");
	for(i=0; i<10; i++){
		printf("%d ", k[i]);
	}
//	printf("\n");
//	printf("players: %d\n", players);
//	printf("Starting Dominion\n");
	int gameSeed = getRandomNumber(1, 1000000);
//	printf("gameseed: %d\n", gameSeed);

	//test when number of players is out of bounds
	int players = 1;
	int result = initializeGame(players, k, gameSeed, g);
	assert(result < 0);
	players = 5;
	result = initializeGame(players, k, gameSeed, g);
	assert(result < 0);

	players = getRandomNumber(2, 4);
	result = initializeGame(players, k, gameSeed, g);
	
	assert(players > 1 && players < 5 );
	assert(players == g->numPlayers);
	testHandDeck(g);
	testK(g, k);
	testVictoryCards(g);


}

int main(int argc, char** argv){

	int strm = 2;
	int seed = 5;
	int i;
	prepRandom(strm, seed);

	for(i=0; i<1000; i++){
		struct gameState *g = newGame();
		testInit(g);
		free(g);
	}

	printf("Tests Passed\n");
	return 0;
}
